package com.watson.onebox.jvm;

import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.Random;
import java.util.concurrent.Semaphore;

public class MyThread implements Runnable {
    private static final int _1MB = 1024 * 1024;


    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static Semaphore semaphore = new Semaphore(50, true);

    @Override
    public void run() {
        try {
            semaphore.acquire();
            byte[] allocation1 = new byte[2 * _1MB];
            byte[] allocation2 = new byte[2 * _1MB];
            for (int i = 0; i < allocation1.length; i++) {
                allocation1[i] = (byte) (System.currentTimeMillis()%100);
            }
            for (int i = 0; i < allocation2.length; i++) {
                allocation2[i] = (byte) (System.nanoTime()%100);
            }

//            System.out.println("allocation1:0x00000000" + Long.toHexString(addressOf(allocation1)));
//            System.out.println("allocation2:0x00000000" + Long.toHexString(addressOf(allocation2)));
            Random random = new Random();
            int s = random.nextInt(10000) % (10000 - 1000 + 1) + 1000;
//            System.out.println(s);
            Thread.sleep(s);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    }

    private static Unsafe unsafe;

    public static long addressOf(Object o) throws Exception {
        Object[] array = new Object[]{o};
        long baseOffset = unsafe.arrayBaseOffset(Object[].class);
        int addressSize = unsafe.addressSize();
        long objectAddress;
        switch (addressSize) {
            case 4:
                objectAddress = unsafe.getInt(array, baseOffset);
                break;
            case 8:
                objectAddress = unsafe.getLong(array, baseOffset);
                break;
            default:
                throw new Error("unsupported address size: " + addressSize);
        }
        return (objectAddress);
    }
}
